package dao

import (
	"encoding/json"
	"errors"
	"fmt"
	"hospital-srv/handler/models"
	"log"
	"time"
)

// 定义清洗结果结构
type CleanResult struct {
	Valid  bool     `json:"valid"`
	Errors []string `json:"errors"`
}

// 批量清洗结果结构
type BatchCleanResult struct {
	AllValid bool          `json:"all_valid"`
	Results  []CleanResult `json:"results"`
}

// 返回值：清理代码切片（错误/提示列表）、消息字符串、错误
func ProcessMqttDataAndPersist(collect models.Collect) ([]string, CleanResult, error) {
	payload, err := json.Marshal(&collect)
	if err != nil {
		return nil, CleanResult{}, err
	}
	date, err := CleanMQTTDate(payload)
	log.Println(date)
	if date.Valid {
		h := models.HealthDatas{
			UserId:          uint(collect.UserId),
			EquipmentId:     uint(collect.DeviceID),
			BodyTemperature: collect.TempValue,
			BloodSugar:      collect.BloodSugarValue,
			BloodPressure:   collect.SystolicBloodPressureValue,
			BloodPressureD:  collect.DiastolicBloodPressureValue,
			BloodOxygen:     collect.BloodOxygenValue,
			CreatedAt:       time.Now(),
		}
		if err := h.CreateHealthDataToMongoDB(); err != nil {
			return date.Errors, CleanResult{}, errors.New("存入MongoDB失败")
		}
		return date.Errors, CleanResult{
			Valid:  false,
			Errors: date.Errors,
		}, nil
	}
	// 数据无效时返回错误代码切片和提示消息
	return date.Errors, CleanResult{}, nil
}

// 清洗 MQTT 接收的数据，判断合理性
func CleanMQTTDate(data []byte) (CleanResult, error) {
	//将数据转json形式
	var collect models.Collect
	if err := json.Unmarshal(data, &collect); err != nil {
		return CleanResult{}, errors.New("解析数据失败: " + err.Error())
	}

	result := CleanResult{
		Valid:  true,
		Errors: []string{},
	}

	// 基础业务前置校验：用户/设备
	if collect.UserId <= 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "用户ID无效")
		return result, nil
	}
	if collect.DeviceID <= 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "设备ID无效")
		return result, nil
	}

	// 检查数据是否为空 - 只报告第一个为空的数据
	if collect.TempValue == 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "体温数据为空")
		return result, nil
	}
	if collect.BloodSugarValue == 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "血糖数据为空")
		return result, nil
	}

	if collect.SystolicBloodPressureValue == 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "血压收缩压数据为空")
		return result, nil
	}
	if collect.DiastolicBloodPressureValue == 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "血压舒张压数据为空")
		return result, nil
	}

	if collect.BloodOxygenValue == 0 {
		result.Valid = false
		result.Errors = append(result.Errors, "血氧数据为空")
		return result, nil
	}

	// 设备上报极端值拦截（强校验，认为数据异常）
	// 体温生理极限：32 - 43（此范围外直接判定为异常上报）
	if collect.TempValue < 32.0 || collect.TempValue > 43.0 {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("体温 %.1f℃ 超出生理极限（32 - 43℃），疑似设备上报异常", collect.TempValue))
	}
	// 血糖设备极限：2 - 33 mmol/L（常见家用血糖仪可测范围），超出视为异常
	if collect.BloodSugarValue < 2.0 || collect.BloodSugarValue > 33.0 {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("血糖 %.1f mmol/L 超出设备合理范围（2 - 33 mmol/L），疑似上报异常", collect.BloodSugarValue))
	}
	// 血压设备极限：收缩压 60-300，舒张压 30-200
	if collect.SystolicBloodPressureValue < 60 || collect.SystolicBloodPressureValue > 300 {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("收缩压 %v mmHg 超出设备合理范围（60 - 300 mmHg）", collect.SystolicBloodPressureValue))
	}
	if collect.DiastolicBloodPressureValue < 30 || collect.DiastolicBloodPressureValue > 200 {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("舒张压 %v mmHg 超出设备合理范围（30 - 200 mmHg）", collect.DiastolicBloodPressureValue))
	}
	// 血氧设备极限：70-100
	if collect.BloodOxygenValue < 70 || collect.BloodOxygenValue > 100 {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("血氧 %v%% 超出设备合理范围（70 - 100%%）", collect.BloodOxygenValue))
	}
	// 按时段体温参考范围
	now := time.Now()
	hour := now.Hour()
	var tempMin, tempMax float32
	var tempWindow string
	switch {
	case hour >= 5 && hour < 11:
		tempMin, tempMax = 36.0, 37.0
		tempWindow = "清晨/上午(05:00-11:00)"
	case hour >= 11 && hour < 17:
		tempMin, tempMax = 36.1, 37.2
		tempWindow = "中午/下午(11:00-17:00)"
	case hour >= 17 && hour < 23:
		tempMin, tempMax = 36.2, 37.4
		tempWindow = "傍晚/夜间(17:00-23:00)"
	default:
		tempMin, tempMax = 36.0, 37.0
		tempWindow = "深夜/凌晨(23:00-05:00)"
	}
	if collect.TempValue != 0 && (collect.TempValue < tempMin || collect.TempValue > tempMax) {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("体温 %.1f℃ 超出按时段参考范围（%s：%.1f - %.1f℃）", collect.TempValue, tempWindow, tempMin, tempMax))
	}

	// 按时段的血糖参考范围（近似：清晨为空腹；餐后2小时三个窗口；其他时段一般上限11.1）
	isFasting := hour >= 5 && hour < 9
	isPostMeal := (hour >= 9 && hour < 11) || (hour >= 14 && hour < 16) || (hour >= 19 && hour < 21)
	if collect.BloodSugarValue != 0 {
		if isFasting {
			if collect.BloodSugarValue < 3.9 || collect.BloodSugarValue > 6.1 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血糖 %.1f mmol/L 超出空腹参考范围（05:00-09:00：3.9 - 6.1 mmol/L）", collect.BloodSugarValue))
			}
		} else if isPostMeal {
			if collect.BloodSugarValue > 11.1 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血糖 %.1f mmol/L 超出餐后2小时参考上限（< 11.1 mmol/L）", collect.BloodSugarValue))
			} else if collect.BloodSugarValue > 7.8 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血糖 %.1f mmol/L 餐后偏高（> 7.8 mmol/L）", collect.BloodSugarValue))
			}
		} else {
			// 其他时段：严格上限按11.1，偏高阈值7.8
			if collect.BloodSugarValue > 11.1 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血糖 %.1f mmol/L 超出一般参考上限（< 11.1 mmol/L）", collect.BloodSugarValue))
			} else if collect.BloodSugarValue > 7.8 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血糖 %.1f mmol/L 偏高（> 7.8 mmol/L）", collect.BloodSugarValue))
			}
		}
	}
	// 收缩压合理范围：90 - 140 mmHg
	if collect.SystolicBloodPressureValue != 0 && (collect.SystolicBloodPressureValue < 90 || collect.SystolicBloodPressureValue > 140) {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("收缩压 %v mmHg 超出合理范围（90 - 140 mmHg）", collect.SystolicBloodPressureValue))
	}

	// 舒张压合理范围：60 - 90 mmHg
	if collect.DiastolicBloodPressureValue != 0 && (collect.DiastolicBloodPressureValue < 60 || collect.DiastolicBloodPressureValue > 90) {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("舒张压 %v mmHg 超出合理范围（60 - 90 mmHg）", collect.DiastolicBloodPressureValue))
	}

	// 夜间血压更严格参考（23:00-05:00）：建议 SBP ≤ 130、DBP ≤ 80
	if hour >= 23 || hour < 5 {
		if collect.SystolicBloodPressureValue > 130 || collect.DiastolicBloodPressureValue > 80 {
			result.Valid = false
			result.Errors = append(result.Errors, "夜间血压偏高：建议≤130/80 mmHg")
		}
	}

	// 血压关系校验：收缩压应大于舒张压；差压（收缩-舒张）建议 20-60
	if collect.SystolicBloodPressureValue > 0 && collect.DiastolicBloodPressureValue > 0 {
		if collect.SystolicBloodPressureValue <= collect.DiastolicBloodPressureValue {
			result.Valid = false
			result.Errors = append(result.Errors, "血压关系异常：收缩压应大于舒张压")
		} else {
			delta := collect.SystolicBloodPressureValue - collect.DiastolicBloodPressureValue
			if delta < 20 || delta > 60 {
				result.Valid = false
				result.Errors = append(result.Errors,
					fmt.Sprintf("血压差压异常：%v mmHg（建议 20 - 60 mmHg）", delta))
			}
		}
	}

	// 血氧合理范围：95 - 100 %
	if collect.BloodOxygenValue != 0 && (collect.BloodOxygenValue < 95 || collect.BloodOxygenValue > 100) {
		result.Valid = false
		result.Errors = append(result.Errors,
			fmt.Sprintf("血氧 %v%% 超出合理范围（95 - 100 %%）", collect.BloodOxygenValue))
	}

	// 危急值提示（标记为无效，提示业务侧需要人工关注）
	if collect.SystolicBloodPressureValue >= 180 || collect.DiastolicBloodPressureValue >= 120 {
		result.Valid = false
		result.Errors = append(result.Errors, "血压危急值：疑似高血压危象（≥180/≥120）")
	}
	if collect.SystolicBloodPressureValue < 90 && collect.DiastolicBloodPressureValue < 60 {
		result.Valid = false
		result.Errors = append(result.Errors, "血压过低：疑似低血压（<90/<60）")
	}
	if collect.BloodSugarValue >= 13.9 {
		result.Valid = false
		result.Errors = append(result.Errors, "血糖危急值：≥13.9 mmol/L，建议尽快复测/就医")
	}
	if collect.BloodSugarValue > 0 && collect.BloodSugarValue < 3.0 {
		result.Valid = false
		result.Errors = append(result.Errors, "血糖过低：<3.0 mmol/L，建议立即干预")
	}
	if collect.BloodOxygenValue > 0 && collect.BloodOxygenValue < 90 {
		result.Valid = false
		result.Errors = append(result.Errors, "血氧过低：<90%，建议尽快复测/吸氧/就医")
	}

	return result, nil
}
